﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Max;
using Autodesk.Max.BaseInterface;
using Autodesk.Max.Editor_Interface;
using Autodesk.Max.IGameObject;
using Autodesk.Max.IKSys;
using Autodesk.Max.Interface;
using Autodesk.Max.Interface10;
using Autodesk.Max.Interface13;
using Autodesk.Max.MaxSDK;
using Autodesk.Max.ObjectWrapper;
using Autodesk.Max.PF;
using Autodesk.Max.Plugins;
using Autodesk.Max.ISceneTraversal;
using Autodesk.Max.IGameControl;

namespace X3DExporter
{
    public class Hwnd32 : System.Windows.Forms.IWin32Window
    {
        private IntPtr m_hwnd;

        public Hwnd32(IntPtr handle)
        {
            m_hwnd = handle;
        }

        public IntPtr Handle
        {
            get { return m_hwnd; }
        }
    }

    public class X3DExporterDescriptor : ClassDesc2
    {
        private IGlobal m_global;
        private static IClass_ID s_classID;

        public X3DExporterDescriptor(IGlobal global)
        {
            m_global = global;
            s_classID = global.Class_ID.Create(8264, 9283472);
        }

        public override string Category
        {
            get { return "X3D Exporter"; }
        }

        public override IClass_ID ClassID
        {
            get { return s_classID; }
        }

        public override string ClassName
        {
            get { return "X3DExporter"; }
        }

        public override object Create(bool loading)
        {
            return new X3DExporter(m_global);
        }

        public override bool IsPublic
        {
            get { return true; }
        }

        public override SClass_ID SuperClassID
        {
            get { return SClass_ID.SceneExport; }
        }
    }

    public class X3DExporter : SceneExport
    {
        private IGlobal m_global;

        public X3DExporter(IGlobal global)
        {
            m_global = global;
        }

        public override string AuthorName { get { return "Binary Arch"; } }
        public override string CopyrightMessage { get { return "Copyright 2011 Binary Arch"; } }
        public override int ExtCount { get { return 1; } }
        public override string LongDesc { get { return "Xeno3D X3D Scene Exporter\nWrote by Binary Arch thyselfs 'So you know it's good!'(tm)\nDonate lost kittans to charity. (or money to us)"; } }
        public override string ShortDesc { get { return "X3D Exporter"; } }
        public override uint Version { get { return 1; } }

        public override int DoExport(string name, IExpInterface ei, IInterface i, bool suppressPrompts, uint options)
        {
            //System.Windows.Forms.MessageBox.Show(new Hwnd32(i.MAXHWnd), "X3DExporter.DoExport() called");
            FileStream fs = new FileStream(name, FileMode.Create, FileAccess.Write);
            BinaryWriter bw = new BinaryWriter(fs);
            var gs = i as IIGameScene;
            gs.InitialiseIGame(false);

            for (int j = 0; j < gs.TopLevelNodeCount; j++)
            {
                var node = gs.GetTopLevelNode(j);
                ExportNode(node, bw);

            }
           

            bw.Flush();
            fs.Flush();
            fs.Close();
            fs = null;
            

            return 1;
        }
        public void ExportNode(IIGameNode n, BinaryWriter bw)
        {
            bw.Write(n.Name);
            var io = n.IGameObject;
            switch (io.IGameType)
            {
                case ObjectTypes.Mesh:
                    var m = n as IIGameMesh;
                    WriteVertices(m, bw);
                    WriteFaces(m, bw);
                    break;
            }
        }
        public void WriteVertices(IIGameMesh m, BinaryWriter w)
        {
            w.Write((int)m.NumberOfColorVerts);
            for (int i = 0; i < m.NumberOfColorVerts; i++)
            {
                WriteVertex(m, i, w);
            }
        }
        public void WriteVertex(IIGameMesh m, int i, BinaryWriter w)
        {
            
            WritePoint3(m.GetColorVertex(i), w);
            
        }
        public void WritePoint3(IPoint3 p, BinaryWriter w)
        {
            w.Write((float)p.X);
            w.Write((float)p.Y);
            w.Write((float)p.Z);
        }
        public void WriteFaces(IIGameMesh m, BinaryWriter w)
        {
            w.Write((int)m.NumberOfFaces);
            for (int i = 0; i < m.NumberOfFaces; i++)
            {
                WriteFace(m, i, w);
            }
        }
        public void WriteFace(IIGameMesh m, int i, BinaryWriter w)
        {
            var f = m.GetFace(i);
            w.Write(f.Vert.Length);
            for (int j = 0; j < f.Vert.Length; j++)
            {
                w.Write((int)f.Vert[j]);
            }

        }
        public override string Ext(int n)
        {
            return "X3D";
        }

        public override string OtherMessage1()
        {
            return String.Empty;
        }

        public override string OtherMessage2()
        {
            return String.Empty;
        }

        public override void ShowAbout(IntPtr hWnd)
        {
            System.Windows.Forms.MessageBox.Show(new Hwnd32(hWnd), LongDesc, "About " + ShortDesc);
        }
    }
}
